<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      class HashTbale {
        // 设置私有table
        table = {}

        // 散列函数
        toStrFn(value){
          if(value === null){
            return 'NULL'
          }else if(value === undefined){
            return 'UNDEFINED'
          }else if(typeof value === 'string' || value instanceof String ){
            return value
          }
          // 如果上面的语句都不符合 那么就是复杂数据类型  返回JSON字符串
          return JSON.stringify(value)
        }

        /*
        简单的算法 将key转为hashCode值  后续慢慢改进
        步骤: 
        - 对象 -> 字符串  
        - 字符串 -> charCodeAt+    charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。
        - 防止数字过大 %  进行取余
        */
        hashCode(key){
          if(typeof key === 'number'){
            // 大喜  就是数字型
            return key
          }
          const tablekey = this.toStrFn(key)

          // 经常出现重复的情况  
          // let hash = 0
          // for (let i = 0; i < tablekey.length; i++) {
          //   hash += tablekey.charCodeAt(i)
          // }
          // return hash % 37 // 防止数字过大进行取余 

          // 改进一下 散列函数
          let hash = 5381;
           for (let i = 0; i < tablekey.length; i++) {
            hash = hash *30 + tablekey.charCodeAt(i)
          }
          return hash % 1013

        }


        set(key ,value){
          if(key != null && value != null){
            const hashKey = this.hashCode(key)
            this.table[hashKey] = new realValue(key,value) // 此时的key更不是原始的key 
            return true
          }
          return false
        }

        get(key){
          const valueres = this.table[this.hashCode(key)]
          return valueres == null ? undefined : valueres.value
        }

        remove(key){
          if(this.hashCode(key)){
            delete this.table[this.hashCode(key)]
            return true
          }
          return false
        }
        
      }

      class realValue  {
        constructor(key , value){
          this.key = key
          this.value = value
        }
      }

      const hashmap = new HashTbale()



    </script>
  </body>
</html>
